// This is a simple example.
// You can make a your own header file and set its path to settings.
// (Preferences > Package Settings > Verilog Gadget > Settings - User)
//
//		"header": "Packages/Verilog Gadget/template/verilog_header.v"
//
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2020 All rights reserved
// -----------------------------------------------------------------------------
// Author : yongchan jeon (Kris) poucotm@gmail.com
// File   : test.v
// Create : 2020-05-19 19:10:04
// Revise : 2020-05-19 19:10:04
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------

module FIR_low #(parameter bit_width = 5'd12)(
	input							    	sys_clk,//250k,即采样频率
	input    							    rst_n,
	input   	 	[bit_width-1:0] 	    data_in,//12位有符号数据，我仿真给的是10k正弦波和30k正弦波合成
	output reg      [27:0] 					data_out
);
parameter signed h0  = 12'hffc; //我设计的是31阶滤波器，抽头系数具有对称性
parameter signed h1  = 12'hff6;
parameter signed h2  = 12'hfec;
parameter signed h3  = 12'hfe1;
parameter signed h4  = 12'hfd8;
parameter signed h5  = 12'hfd9;
parameter signed h6  = 12'hfec;
parameter signed h7  = 12'h01a;
parameter signed h8  = 12'h069;
parameter signed h9  = 12'h0dd;
parameter signed h10 = 12'h170;
parameter signed h11 = 12'h219;
parameter signed h12 = 12'h2c6;
parameter signed h13 = 12'h361;
parameter signed h14 = 12'h3d8;
parameter signed h15 = 12'h417;

reg [4:0]  i;
reg [11:0] data_in_1;
reg [11:0] data_in_2;
reg [11:0] sample[31:0];
wire[23:0] mul   [31:0];
always@(posedge sys_clk or negedge rst_n)begin
	if(!rst_n)begin
		data_in_1 <= 'd0;
		data_in_2 <= 'd0;
	end
	else begin
		data_in_1 <= data_in;
		data_in_2 <= data_in_1;
	end
end

always@(posedge sys_clk or negedge rst_n)begin
	if(!rst_n)begin
		for(i=0;i<31;i=i+1'b1)
			sample[i] = 'd0; 
	end
	else begin
		sample [0] <= data_in_2;
		sample [1] <= sample[0];
		sample [2] <= sample[1];
		sample [3] <= sample[2];
		sample [4] <= sample[3];
		sample [5] <= sample[4];
		sample [6] <= sample[5];
		sample [7] <= sample[6];
		sample [8] <= sample[7];
		sample [9] <= sample[8];
		sample [10]<= sample[9];
		sample [11]<= sample[10];
		sample [12]<= sample[11];
		sample [13]<= sample[12];
		sample [14]<= sample[13];
		sample [15]<= sample[14];
		sample [16]<= sample[15];
		sample [17]<= sample[16];
		sample [18]<= sample[17];
		sample [19]<= sample[18];
		sample [20]<= sample[19];
		sample [21]<= sample[20];
		sample [22]<= sample[21];
		sample [23]<= sample[22];
		sample [24]<= sample[23];
		sample [25]<= sample[24];
		sample [26]<= sample[25];
		sample [27]<= sample[26];
		sample [28]<= sample[27];
		sample [29]<= sample[28];
		sample [30]<= sample[29];
		sample [31]<= sample[30];
	end
end

//抽头系数相同的想加
 lpm_mult18x18 lpm_mult18x18_0(
	.clock(sys_clk),
	.dataa(h0),
	.datab(sample[0]),
	.result(mul[0]));
	
 lpm_mult18x18 lpm_mult18x18_1(
	.clock(sys_clk),
	.dataa(h1),
	.datab(sample[1]),
	.result(mul[1]));

 lpm_mult18x18 lpm_mult18x18_2(
	.clock(sys_clk),
	.dataa(h2),
	.datab(sample[2]),
	.result(mul[2]));
	
 lpm_mult18x18 lpm_mult18x18_3(
	.clock(sys_clk),
	.dataa(h3),
	.datab(sample[3]),
	.result(mul[3]));
	
 lpm_mult18x18 lpm_mult18x18_4(
	.clock(sys_clk),
	.dataa(h4),
	.datab(sample[4]),
	.result(mul[4]));

	 lpm_mult18x18 lpm_mult18x18_5(
	.clock(sys_clk),
	.dataa(h5),
	.datab(sample[5]),
	.result(mul[5]));
	
	 lpm_mult18x18 lpm_mult18x18_6(
	.clock(sys_clk),
	.dataa(h6),
	.datab(sample[6]),
	.result(mul[6]));
	
	 lpm_mult18x18 lpm_mult18x18_7(
	.clock(sys_clk),
	.dataa(h7),
	.datab(sample[7]),
	.result(mul[7]));
	
	 lpm_mult18x18 lpm_mult18x18_8(
	.clock(sys_clk),
	.dataa(h8),
	.datab(sample[8]),
	.result(mul[8]));
	
	 lpm_mult18x18 lpm_mult18x18_9(
	.clock(sys_clk),
	.dataa(h9),
	.datab(sample[9]),
	.result(mul[9]));
	
	 lpm_mult18x18 lpm_mult18x18_10(
	.clock(sys_clk),
	.dataa(h10),
	.datab(sample[10]),
	.result(mul[10]));
	
	 lpm_mult18x18 lpm_mult18x18_11(
	.clock(sys_clk),
	.dataa(h11),
	.datab(sample[11]),
	.result(mul[11]));
	
lpm_mult18x18 lpm_mult18x18_12(
	.clock(sys_clk),
	.dataa(h12),
	.datab(sample[12]),
	.result(mul[12]));
	
	lpm_mult18x18 lpm_mult18x18_13(
	.clock(sys_clk),
	.dataa(h13),
	.datab(sample[13]),
	.result(mul[13]));
	
	lpm_mult18x18 lpm_mult18x18_14(
	.clock(sys_clk),
	.dataa(h14),
	.datab(sample[14]),
	.result(mul[14]));
	
	lpm_mult18x18 lpm_mult18x18_15(
	.clock(sys_clk),
	.dataa(h15),
	.datab(sample[15]),
	.result(mul[15]));
	
		lpm_mult18x18 lpm_mult18x18_16(
	.clock(sys_clk),
	.dataa(h15),
	.datab(sample[16]),
	.result(mul[16]));
	
		lpm_mult18x18 lpm_mult18x18_17(
	.clock(sys_clk),
	.dataa(h14),
	.datab(sample[17]),
	.result(mul[17]));
	
		lpm_mult18x18 lpm_mult18x18_18(
	.clock(sys_clk),
	.dataa(h13),
	.datab(sample[18]),
	.result(mul[18]));
	
		lpm_mult18x18 lpm_mult18x18_19(
	.clock(sys_clk),
	.dataa(h12),
	.datab(sample[19]),
	.result(mul[19]));
	
		lpm_mult18x18 lpm_mult18x18_20(
	.clock(sys_clk),
	.dataa(h11),
	.datab(sample[20]),
	.result(mul[20]));
	
		lpm_mult18x18 lpm_mult18x18_21(
	.clock(sys_clk),
	.dataa(h10),
	.datab(sample[21]),
	.result(mul[21]));
	
lpm_mult18x18 lpm_mult18x18_22(
	.clock(sys_clk),
	.dataa(h9),
	.datab(sample[22]),
	.result(mul[22]));
	
	lpm_mult18x18 lpm_mult18x18_23(
	.clock(sys_clk),
	.dataa(h8),
	.datab(sample[23]),
	.result(mul[23]));
	
	lpm_mult18x18 lpm_mult18x18_24(
	.clock(sys_clk),
	.dataa(h7),
	.datab(sample[24]),
	.result(mul[24]));
	
	lpm_mult18x18 lpm_mult18x18_25(
	.clock(sys_clk),
	.dataa(h6),
	.datab(sample[25]),
	.result(mul[25]));
	
	lpm_mult18x18 lpm_mult18x18_26(
	.clock(sys_clk),
	.dataa(h5),
	.datab(sample[26]),
	.result(mul[26]));
	
	
	lpm_mult18x18 lpm_mult18x18_27(
	.clock(sys_clk),
	.dataa(h4),
	.datab(sample[27]),
	.result(mul[27]));
	
	
	lpm_mult18x18 lpm_mult18x18_28(
	.clock(sys_clk),
	.dataa(h3),
	.datab(sample[28]),
	.result(mul[28]));
	
	lpm_mult18x18 lpm_mult18x18_29(
	.clock(sys_clk),
	.dataa(h2),
	.datab(sample[29]),
	.result(mul[29]));
	
	lpm_mult18x18 lpm_mult18x18_30(
	.clock(sys_clk),
	.dataa(h1),
	.datab(sample[30]),
	.result(mul[30]));
	
	lpm_mult18x18 lpm_mult18x18_31(
	.clock(sys_clk),
	.dataa(h0),
	.datab(sample[31]),
	.result(mul[31]));
//sum

always@(posedge sys_clk or negedge rst_n)begin
	if(!rst_n)begin
			data_out  <= 'd0;
	end
	else begin
		data_out <=  {mul[0 ] [23], mul[0 ][23], mul[0 ][23], mul[0 ][23],mul[0 ] }
					  + { mul[1 ][23], mul[1 ][23], mul[1 ][23], mul[1 ][23],mul[1 ] }
					  + { mul[2 ][23], mul[2 ][23], mul[2 ][23], mul[2 ][23],mul[2 ] }
					  + { mul[3 ][23], mul[3 ][23], mul[3 ][23], mul[3 ][23],mul[3 ] }
					  + { mul[4 ][23], mul[4 ][23], mul[4 ][23], mul[4 ][23],mul[4 ] }
					  + { mul[5 ][23], mul[5 ][23], mul[5 ][23], mul[5 ][23],mul[5 ] }
					  + { mul[6 ][23], mul[6 ][23], mul[6 ][23], mul[6 ][23],mul[6 ] }
					  + { mul[7 ][23], mul[7 ][23], mul[7 ][23], mul[7 ][23],mul[7 ] }
					  + { mul[8 ][23], mul[8 ][23], mul[8 ][23], mul[8 ][23],mul[8 ] }
					  + { mul[9 ][23], mul[9 ][23], mul[9 ][23], mul[9 ][23],mul[9 ] }
					  + { mul[10][23], mul[10][23], mul[10][23], mul[10][23],mul[10] }
					  + { mul[11][23], mul[11][23], mul[11][23], mul[11][23],mul[11] }
					  + { mul[12][23], mul[12][23], mul[12][23], mul[12][23],mul[12] }
					  + { mul[13][23], mul[13][23], mul[13][23], mul[13][23],mul[13] }
				      + { mul[14][23], mul[14][23], mul[14][23], mul[14][23],mul[14] }
			          + { mul[15][23], mul[15][23], mul[15][23], mul[15][23],mul[15] }
			          + { mul[16][23], mul[16][23], mul[16][23], mul[16][23],mul[16] }
			          + { mul[17][23], mul[17][23], mul[17][23], mul[17][23],mul[17] }
			          + { mul[18][23], mul[18][23], mul[18][23], mul[18][23],mul[18] }
			          + { mul[19][23], mul[19][23], mul[19][23], mul[19][23],mul[19] }
			          + { mul[20][23], mul[20][23], mul[20][23], mul[20][23],mul[20] }
			          + { mul[21][23], mul[21][23], mul[21][23], mul[21][23],mul[21] }
			          + { mul[22][23], mul[22][23], mul[22][23], mul[22][23],mul[22] }
			          + { mul[23][23], mul[23][23], mul[23][23], mul[23][23],mul[23] }
			          + { mul[24][23], mul[24][23], mul[24][23], mul[24][23],mul[24] }
			          + { mul[25][23], mul[25][23], mul[25][23], mul[25][23],mul[25] }
			          + { mul[26][23], mul[26][23], mul[26][23], mul[26][23],mul[26] }
			          + { mul[27][23], mul[27][23], mul[27][23], mul[27][23],mul[27] }
			          + { mul[28][23], mul[28][23], mul[28][23], mul[28][23],mul[28] }
			          + { mul[29][23], mul[29][23], mul[29][23], mul[29][23],mul[29] }
			          + { mul[30][23], mul[30][23], mul[30][23], mul[30][23],mul[30] }
			          + { mul[31][23], mul[31][23], mul[31][23], mul[31][23],mul[31] }; 
	end
end

endmodule
